"""
自定义认证后端
支持学生通过学号、用户名、手机号、邮箱登录
"""
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.db.models import Q

User = get_user_model()


class MultiFieldAuthBackend(ModelBackend):
    """
    支持多字段认证的后端
    学生可以通过以下方式登录：
    1. 用户名 (username)
    2. 学号 (通过关联的Student模型)
    3. 手机号 (phone)
    4. 邮箱 (email)
    """
    
    def authenticate(self, request, username=None, password=None, **kwargs):
        if username is None or password is None:
            return None
        
        # 尝试通过多种方式查找用户
        user = self._get_user_by_identifier(username)
        
        if user and user.check_password(password):
            return user
        
        return None
    
    def _get_user_by_identifier(self, identifier):
        """
        通过多种标识符查找用户
        """
        try:
            # 1. 直接通过用户名查找
            user = User.objects.get(username=identifier)
            return user
        except User.DoesNotExist:
            pass
        
        try:
            # 2. 通过邮箱查找
            user = User.objects.get(email=identifier)
            return user
        except User.DoesNotExist:
            pass
        
        try:
            # 3. 通过手机号查找
            user = User.objects.get(phone=identifier)
            return user
        except User.DoesNotExist:
            pass
        
        try:
            # 4. 通过学号查找（需要导入Student模型）
            from students.models import Student
            student = Student.objects.select_related('user').get(student_id=identifier)
            if student.user:
                return student.user
        except (Student.DoesNotExist, ImportError):
            pass
        
        # 5. 通过学生的手机号或邮箱查找
        try:
            from students.models import Student
            # 通过学生的手机号查找
            student = Student.objects.select_related('user').get(phone=identifier)
            if student.user:
                return student.user
        except (Student.DoesNotExist, ImportError):
            pass
        
        try:
            from students.models import Student
            # 通过学生的邮箱查找
            student = Student.objects.select_related('user').get(email=identifier)
            if student.user:
                return student.user
        except (Student.DoesNotExist, ImportError):
            pass
        
        return None
    
    def get_user(self, user_id):
        """
        通过用户ID获取用户
        """
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None


class StudentAuthBackend(ModelBackend):
    """
    专门为学生设计的认证后端
    优先通过学号进行认证
    """
    
    def authenticate(self, request, username=None, password=None, **kwargs):
        if username is None or password is None:
            return None
        
        # 首先尝试作为学号查找
        user = self._get_user_by_student_id(username)
        if user and user.check_password(password):
            return user
        
        # 如果不是学号，尝试其他方式
        return super().authenticate(request, username, password, **kwargs)
    
    def _get_user_by_student_id(self, student_id):
        """
        通过学号查找用户
        """
        try:
            from students.models import Student
            student = Student.objects.select_related('user').get(student_id=student_id)
            return student.user
        except (Student.DoesNotExist, ImportError):
            return None
